package org.truenewx.tnxjee.repo.mybatis;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

import org.truenewx.tnxjee.model.entity.Entity;
import org.truenewx.tnxjee.repo.mybatis.mapper.EntityMapper;
import org.truenewx.tnxjee.repo.support.EntityClassProvider;

public abstract class MyBatisEntityMapperRepository<T extends Entity, K extends Serializable>
        implements MyBatisRepository<T, K>, EntityClassProvider {

    protected abstract EntityMapper<T> getMapper();

    @Override
    public <S extends T> S save(S entity) {
        getMapper().save(entity);
        return entity;
    }

    @Override
    public <S extends T> Iterable<S> saveAll(Iterable<S> entities) {
        entities.forEach(this::save);
        return entities;
    }

    @Override
    public Iterable<T> findAllById(Iterable<K> ids) {
        List<T> list = new ArrayList<>();
        ids.forEach(id -> {
            findById(id).ifPresent(list::add);
        });
        return list;
    }

    @Override
    public Iterable<T> findAll() {
        return getMapper().selectList(null);
    }

    @Override
    public long count() {
        return getMapper().selectCount(null);
    }

    @Override
    public void delete(T entity) {
        getMapper().deleteById(entity);
    }

    @Override
    public void deleteAllById(Iterable<? extends K> ids) {
        ids.forEach(this::deleteById);
    }

    @Override
    public void deleteAll(Iterable<? extends T> entities) {
        entities.forEach(this::delete);
    }

    @Override
    public void deleteAll() {
        getMapper().delete(null);
    }

    @Override
    public Optional<T> findById(K id) {
        T entity = getMapper().selectById(id);
        return Optional.ofNullable(entity);
    }

    @Override
    public void deleteById(K id) {
        getMapper().deleteById(id);
    }

}
